package com.raincat.tools.multimediapickertools.utils;

import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.provider.MediaStore;
import android.provider.MediaStore.Images.Media;

import com.raincat.tools.R;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;

/**
 * <pre>
 *     author : RainCat
 *     org    : Shenzhen JingYu Network Technology Co., Ltd.
 *     e-mail : nining377@gmail.com
 *     time   : 2019/02/15
 *     desc   : 多媒体获取帮助类
 *     version: 1.0
 * </pre>
 */

public class MultiMediaHelper {
    private ContentResolver cr;
    // 专辑列表
    private List<MultiMediaBucket> multiMediaBucketList = new ArrayList<>();
    // 最新的一张图片
    private String lastImgPath = "";
    // 单例模式
    private static MultiMediaHelper instance;

    // 图片获取完毕回调
    public interface onBucketListGetListener {
        void onFinish(List<MultiMediaBucket> bucketList);
    }

    public static MultiMediaHelper getInstance(Context context) {
        if (instance == null) {
            instance = new MultiMediaHelper(context.getApplicationContext());
        }
        return instance;
    }

    private MultiMediaHelper(Context context) {
        init(context);
    }

    public static void onDestroy() {
        instance = null;
    }

    /**
     * 初始化
     */
    private void init(Context context) {
        if (cr == null) {
            cr = context.getContentResolver();
        }
    }

    /**
     * 获取多媒体集，外部调用，异步
     */
    public void getMultiMediaBucketList(final Context context, final boolean isPickVideo, final boolean isPickGif, final onBucketListGetListener b) {
        // 构造相册索引(异步)
        new Thread(new Runnable() {
            @Override
            public void run() {
                getMultiMediaBucketListSync(context, isPickVideo, isPickGif, b);
            }
        }).start();
    }

    /**
     * 检查最新一张图片的路径变化判断是否需要刷新图片列表
     *
     * @return true需要刷新
     */
    private boolean isShouldRefresh() {
        // 构造相册索引
        String[] columns = new String[]{Media.DATA};
        // 得到一个游标，时间从新到旧读取
        Cursor cur = cr.query(Media.EXTERNAL_CONTENT_URI, columns, null, null, Media.DATE_MODIFIED + " desc");
        if (cur != null && cur.getCount() > 0) {
            cur.moveToNext();
            // 获取指定列的索引
            String path = cur.getString(cur.getColumnIndexOrThrow(Media.DATA));
            cur.close();
            if (path.equals(lastImgPath)) {
                return false;
            } else {
                lastImgPath = path;
                return true;
            }
        } else
            return false;
    }

    /**
     * 从数据库读取图片集，同一时间只能进入一次，第二次之后直接返回数据
     */
    private synchronized void getMultiMediaBucketListSync(final Context context, final boolean isPickVideo,
                                                          final boolean isPickGif, final onBucketListGetListener b) {
        if (!isShouldRefresh() && multiMediaBucketList.size() != 0) {
            if (b != null)
                b.onFinish(multiMediaBucketList);
            return;
        }

        multiMediaBucketList.clear();
        List<MultiMediaItem> allImageItemList = new ArrayList<>();
        // 哈希链表，遍历的时候会从最开始加入的数据开始读出
        LinkedHashMap<String, MultiMediaBucket> bucketMap = new LinkedHashMap<>();
        String[] columns = new String[]{Media._ID, Media.BUCKET_ID, Media.DATA, Media.DISPLAY_NAME, Media.SIZE, Media.BUCKET_DISPLAY_NAME, Media.DATE_MODIFIED};
        // 得到一个游标，时间从新到旧读取
        Cursor cur = cr.query(Media.EXTERNAL_CONTENT_URI, columns, null, null, Media.DATE_MODIFIED + " desc");
        if (cur.moveToFirst()) {
            // 获取指定列的索引
            int photoIDIndex = cur.getColumnIndexOrThrow(Media._ID);
            int photoPathIndex = cur.getColumnIndexOrThrow(Media.DATA);
            int bucketDisplayNameIndex = cur.getColumnIndexOrThrow(Media.BUCKET_DISPLAY_NAME);
            int bucketIdIndex = cur.getColumnIndexOrThrow(Media.BUCKET_ID);
            int addTime = cur.getColumnIndexOrThrow(Media.DATE_MODIFIED);
            int photoSizeIndex = cur.getColumnIndexOrThrow(Media.SIZE);
            do {
                String _id = cur.getString(photoIDIndex);
                String path = cur.getString(photoPathIndex);
                String bucketName = cur.getString(bucketDisplayNameIndex);
                String bucketId = cur.getString(bucketIdIndex);
                long bucketTime = cur.getLong(addTime);
                String size = cur.getString(photoSizeIndex);

                // 文件为空或者文件太小的不保存
                if (size == null || Float.parseFloat(size) <= 1024 || !ImageCacheUtils.fileIsExists(path)) {
                    continue;
                }

                if (!isPickGif) {
                    String suffix = path.substring((path.lastIndexOf(".") + 1));
                    if (suffix.equalsIgnoreCase("gif"))
                        continue;
                }

                MultiMediaBucket bucket;
                if (bucketMap.get(bucketId) == null) {
                    bucket = new MultiMediaBucket();
                    bucket.bucketName = bucketName;
                    bucketMap.put(bucketId, bucket);
                } else {
                    bucket = bucketMap.get(bucketId);
                    assert bucket != null;
                    bucket.bucketName = bucketName;
                }

                bucket.count++;
                MultiMediaItem item = new MultiMediaItem();
                item.id = _id;
                item.path = path;
                item.addTime = bucketTime;
                item.size = Float.parseFloat(size);
                item.suffix = path.substring((path.lastIndexOf(".") + 1));
                item.mimeType = "image";

                bucket.multiMediaItemList.add(item);
            } while (cur.moveToNext());
        }
        cur.close();
        for (MultiMediaBucket multiMediaBucket : bucketMap.values()) {
            allImageItemList.addAll(multiMediaBucket.multiMediaItemList);
            multiMediaBucketList.add(multiMediaBucket);
        }
        if (b != null) {
            MultiMediaBucket bucket = new MultiMediaBucket();
            bucket.bucketName = context.getString(R.string.picker_all_photos);
            bucket.count = allImageItemList.size();
            bucket.multiMediaItemList = allImageItemList;
            multiMediaBucketList.add(0, bucket);
            if (isPickVideo) {
                multiMediaBucketList.add(1, getVideosBucketList(context));
            }

            b.onFinish(multiMediaBucketList);
        }
    }

    /**
     * 从数据库读取视频集
     */
    public MultiMediaBucket getVideosBucketList(final Context context) {
        MultiMediaBucket bucket = new MultiMediaBucket();
        List<MultiMediaItem> multiMediaItemList = new ArrayList<>();
        String[] columns = new String[]{MediaStore.Video.Media._ID, MediaStore.Video.Media.DATA, MediaStore.Video.Media.SIZE, MediaStore.Video.Media.DATE_MODIFIED, MediaStore.Video.Media.DURATION};
        // 得到一个游标，时间从新到旧读取
        Cursor cur = cr.query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, columns, null, null, MediaStore.Video.Media.DATE_MODIFIED + " desc");

        if (cur.moveToFirst()) {
            // 获取指定列的索引
            int videoIDIndex = cur.getColumnIndexOrThrow(MediaStore.Video.Media._ID);
            int videoPathIndex = cur.getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
            int addTime = cur.getColumnIndexOrThrow(MediaStore.Video.Media.DATE_MODIFIED);
            int videoSizeIndex = cur.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE);
            int videoDurationIndex = cur.getColumnIndexOrThrow(MediaStore.Video.Media.DURATION);
            do {
                String _id = cur.getString(videoIDIndex);
                String path = cur.getString(videoPathIndex);
                long bucketTime = cur.getLong(addTime);
                String size = cur.getString(videoSizeIndex);
                long duration = cur.getLong(videoDurationIndex);

                // 文件为空或者文件太小的不保存
                if (size == null || Float.parseFloat(size) <= 1024 || !ImageCacheUtils.fileIsExists(path)) {
                    continue;
                }


                MultiMediaItem item = new MultiMediaItem();
                item.id = _id;
                item.path = path;
                item.addTime = bucketTime;
                item.size = Float.parseFloat(size);
                item.suffix = path.substring((path.lastIndexOf(".") + 1));
                item.duration = millisecond2Time(duration);
                item.durationStamp = duration;
                item.mimeType = "video";

                multiMediaItemList.add(item);
            } while (cur.moveToNext());
        }
        cur.close();

        bucket.bucketName = context.getString(R.string.picker_all_videos);
        bucket.count = multiMediaItemList.size();
        bucket.multiMediaItemList = multiMediaItemList;

        return bucket;
    }

    //毫秒转时间
    private String millisecond2Time(long millisecond) {
        long second = millisecond / 1000 % 60;
        long min = millisecond / 1000 / 60 % 60;
        long hour = millisecond / 1000 / 60 / 60;

        String time = String.format(Locale.getDefault(), "%02d", hour);
        time = time + ":" + String.format(Locale.getDefault(), "%02d", min);
        time = time + ":" + String.format(Locale.getDefault(), "%02d", second);
        return time;
    }
}
